package cn.outsourcing.supermarket.service.impl;

import cn.outsourcing.supermarket.common.PageResult;
import cn.outsourcing.supermarket.common.constants.CommonConstants;
import cn.outsourcing.supermarket.common.enums.GoodsEnum;
import cn.outsourcing.supermarket.common.exception.SupermarketException;
import cn.outsourcing.supermarket.common.utils.IPageUtils;
import cn.outsourcing.supermarket.common.utils.PageResultUtils;
import cn.outsourcing.supermarket.converter.HiolabsGoodsConverter;
import cn.outsourcing.supermarket.dto.CategoryGoodsPageDTO;
import cn.outsourcing.supermarket.dto.GoodsListSearchDTO;
import cn.outsourcing.supermarket.mapper.HiolabsGoodsMapper;
import cn.outsourcing.supermarket.po.HiolabsCategory;
import cn.outsourcing.supermarket.po.HiolabsGoods;
import cn.outsourcing.supermarket.service.*;
import cn.outsourcing.supermarket.vo.CategoryGoodsVO;
import cn.outsourcing.supermarket.vo.DetailSpecificationListVO;
import cn.outsourcing.supermarket.vo.GoodsDetailsVO;
import cn.outsourcing.supermarket.vo.foot.FootGoodsVO;
import cn.outsourcing.supermarket.vo.hiolabs.HiolabsGoodsSpecificationVO;
import cn.outsourcing.supermarket.vo.hiolabs.HiolabsGoodsVO;
import cn.outsourcing.supermarket.vo.hiolabs.HiolabsSpecificationVO;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author gzkemays
 * @since 2021-10-14
 */
@Service
public class HiolabsGoodsServiceImpl extends ServiceImpl<HiolabsGoodsMapper, HiolabsGoods>
    implements HiolabsGoodsService {
  @Resource private HiolabsGoodsMapper goodsMapper;
  @Resource private HiolabsCategoryService categoryService;
  @Resource private HiolabsSearchHistoryService historyService;
  @Resource private HiolabsGoodsSpecificationService goodsSpecificationService;
  @Resource private HiolabsSpecificationService specificationService;
  @Resource private HiolabsGoodsGalleryService galleryService;
  @Resource private HiolabsProductService productService;
  @Resource private HiolabsFootprintService footprintService;

  @Override
  public PageResult<CategoryGoodsVO> getCategoryGoods(
      CategoryGoodsPageDTO categoryGoodsPage, boolean isHome) {
    long categoryId = categoryGoodsPage.getId();
    // 全部分类可见商品
    List<Integer> categoryIds = new ArrayList<>();
    if (categoryId == 0) {
      categoryIds =
          categoryService
              .getBaseMapper()
              .selectList(
                  Wrappers.<HiolabsCategory>lambdaQuery().eq(HiolabsCategory::getIsCategory, 1))
              .stream()
              .map(HiolabsCategory::getId)
              .collect(Collectors.toList());
    }

    Object category =
        categoryIds.isEmpty()
            ? categoryId
            : StringUtils.join(categoryIds, CommonConstants.COMMA_SEPARATOR);
    IPageUtils<HiolabsGoods> pages =
        goodsMapper.selectPage(
            IPageUtils.<HiolabsGoods>init()
                .page(categoryGoodsPage.getPage())
                .limit(categoryGoodsPage.getSize())
                .create(),
            Wrappers.<HiolabsGoods>lambdaQuery()
                .eq(categoryId != 0, HiolabsGoods::getCategoryId, categoryId)
                .eq(HiolabsGoods::getIsDelete, 0)
                .eq(HiolabsGoods::getIsOnSale, 1)
                .eq(isHome, HiolabsGoods::getIsIndex, 1)
                .in(HiolabsGoods::getCategoryId, category)
                .orderByAsc(HiolabsGoods::getSortOrder));

    return PageResultUtils.parseListPageObjs(
        pages, HiolabsGoodsConverter.INSTANCE.convertToCategoryGoodsList(pages.getRecords()));
  }

  @Override
  public GoodsDetailsVO getGoodsDetails(Integer id) {
    // 获取商品基本信息
    HiolabsGoods goods = goodsMapper.selectById(id);
    Integer goodsId = goods.getId();
    // 商品规格列表
    List<HiolabsGoodsSpecificationVO> goodsSpecificationList =
        goodsSpecificationService.getGoodsSpecificationVO(goodsId);
    // 规格 id
    if (goodsSpecificationList.isEmpty()) {
      throw new SupermarketException(GoodsEnum.GOODS_TAKE_DOWN.getCode(),GoodsEnum.GOODS_TAKE_DOWN.getText());
    }
    Integer specificationId = goodsSpecificationList.get(0).getSpecificationId();
    // 规格信息
    HiolabsSpecificationVO specificationVO =
        specificationService.getSpecificationVO(goodsSpecificationList.get(0).getSpecificationId());
    // 插入足迹
    footprintService.addFootPrint(id);

    return GoodsDetailsVO.builder()
        .info(HiolabsGoodsConverter.INSTANCE.convertToVo(goods))
        .gallery(galleryService.getGoodsGallery(goodsId))
        .specificationList(
            DetailSpecificationListVO.builder()
                .specificationId(specificationId)
                .name(specificationVO.getName())
                .valueList(goodsSpecificationList)
                .build())
        .productList(productService.getProductVoByGoodsId(goodsId))
        .build();
  }

  @Override
  public List<HiolabsGoodsVO> getGoodsList(GoodsListSearchDTO entity) {
    List<HiolabsGoodsVO> goodsList = goodsMapper.getGoodsList(entity);
    String keyword = entity.getKeyword();
    // 如果搜索成功而且当前用户没有搜索成功过该数据时，插入历史记录。
    if (!goodsList.isEmpty() && historyService.noneHistory(keyword)) {
      historyService.insertHistory(keyword);
    }
    return goodsMapper.getGoodsList(entity);
  }

  @Override
  public Map<String, Integer> getCount() {
    HashMap<String, Integer> count = new HashMap<>(1);
    List<Integer> categoryIds =
        categoryService.getCategoryList().getCategoryList().stream()
            .map(HiolabsCategory::getId)
            .collect(Collectors.toList());

    List<HiolabsGoods> hiolabsGoods =
        goodsMapper.selectList(
            Wrappers.<HiolabsGoods>lambdaQuery()
                .eq(HiolabsGoods::getIsDelete, 0)
                .in(!categoryIds.isEmpty(), HiolabsGoods::getCategoryId, categoryIds)
                .orderByAsc(HiolabsGoods::getSortOrder));
    count.put("goodsCount", hiolabsGoods.isEmpty() ? 0 : hiolabsGoods.size());
    return count;
  }

  @Override
  public FootGoodsVO getFootGoods(Integer goodsId) {
    HiolabsGoods goods =
        goodsMapper.selectOne(
            Wrappers.<HiolabsGoods>lambdaQuery()
                .eq(HiolabsGoods::getId, goodsId)
                .eq(HiolabsGoods::getIsDelete, 0));
    return HiolabsGoodsConverter.INSTANCE.convertToFoodGoods(goods);
  }

  @Override
  public int reduceStock(Integer goodsId, Integer number) {
    HiolabsGoods goods = goodsMapper.selectById(goodsId);
    goods.setGoodsNumber(goods.getGoodsNumber() - number);
    goods.setSellVolume(goods.getSellVolume() + number);
    return goodsMapper.updateById(goods);
  }
}
